/*
 * @Author: wuqingchun
 * @Date: 2024-04-25 10:51:51
 * @Description: 时间获取工具
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-04-25 15:03:44
 */
#ifndef __PERF_TIME_H__
#define __PERF_TIME_H__

#include <iostream>
#include <cstdint>
#include <time.h>
#include <chrono>

class PerfTime
{
public:
    static uint64_t GetRDTSC()
    {
        //rdtsc
        // RDTSC指令的使用以及相关问题
        // RDTSC—Read Time-Stamp Counter

        /* 
        Opcode        Instruction              Description
        0F 31         RDTSC Read time-stamp    counter into EDX:EAX

        https://blog.csdn.net/redchairman/article/details/5352033
        */
#ifdef i386
        uint32_t uiRDTSC;
        __volatile__ ("rdtsc" : "=A" (uiRDTSC));
        return uiRDTSC;
#elif defined __x86_64__
        uint32_t uiLow, uiHigh;
        __asm__ volatile ("rdtsc":"=a"(uiLow), "=d"(uiHigh):);
        return ((uint64_t)uiHigh << 32) | uiLow;
#elif defined __ia64__
        uint64_t ui64HighPrecisionTime;
        __asm__ __volatile__ ("mov %0=ar.itc" : "=r" (ui64HighPrecisionTime) : : "memory");

        return ui64HighPrecisionTime;
#else
//#error "Unsupport rdtsc instruction"
#warning "Unsupport rdtsc instruction"
#endif
        return 0;
    }

    static uint64_t GetClockTime()
    {
        timespec stTmSpec;
        (void)clock_gettime(CLOCK_MONOTONIC, &stTmSpec);

        // std::cout << "sec: " << stTmSpec.tv_sec << std::endl
        //           << "nsec: " << stTmSpec.tv_nsec << std::endl;
        return stTmSpec.tv_sec * 1000000000 + stTmSpec.tv_nsec;
    }

    static uint64_t GetChronoTime()
    {
        return std::chrono::steady_clock::now().time_since_epoch().count();
    }
};

#endif //__PERF_TIME_H__